home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World's Largest Collection of Windows Software
/
The World's Largest Collection of Windows Software - Disc 2.iso
/
textproc
/
_j1
/
tex2rtf
/
src
/
htmlutil.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-26
|
23KB
|
969 lines
/*
* htmlutil.cc
*
* Utility functions for helping convert Latex files
* into HTML files.
* files.
*
* Julian Smart September 1993
*
*/
#include <wx.h>
#include "tex2any.h"
#include "tex2rtf.h"
char *ChaptersName = NULL;
char *SectionsName = NULL;
char *SubsectionsName = NULL;
char *SubsubsectionsName = NULL;
static TexChunk *descriptionItemArg = NULL;
static TexChunk *helpRefFilename = NULL;
static TexChunk *helpRefText = NULL;
static int indentLevel = 0;
extern FILE *Contents;
FILE *Titlepage = NULL;
int fileId = 0;
// Are we in verbatim mode? If so, format differently.
static Bool inVerbatim = FALSE;
// This is defined in the Tex2Any library.
extern char *BigBuffer;
class HyperReference: public wxObject
{
public:
char *refName;
char *refFile;
HyperReference(char *name, char *file)
{
if (name) refName = copystring(name);
if (file) refFile = copystring(file);
}
};
/*
* Close former filedescriptor and reopen using another filename.
*
*/
void ReopenFile(FILE **fd, char **fileName)
{
if (*fd)
{
fclose(*fd);
}
fileId ++;
char buf[200];
sprintf(buf, "%s%d.html", FileRoot, fileId);
if (*fileName) delete[] *fileName;
*fileName = copystring(FileNameFromPath(buf));
*fd = fopen(buf, "w");
}
/*
* Given a TexChunk with a string value, scans through the string
* converting Latex-isms into HTML-isms, such as 2 newlines -> <P>.
*
*/
void ProcessText2HTML(TexChunk *chunk)
{
Bool changed = FALSE;
int ptr = 0;
int i = 0;
char ch = 1;
int len = strlen(chunk->value);
while (ch != 0)
{
ch = chunk->value[i];
// 2 newlines means \par
if (!inVerbatim && chunk->value[i] == 10 && ((len > i+1 && chunk->value[i+1] == 10) ||
((len > i+1 && chunk->value[i+1] == 13) &&
(len > i+2 && chunk->value[i+2] == 10))))
{
BigBuffer[ptr] = 0; strcat(BigBuffer, "<P>\n\n"); ptr += 5;
i += 2;
changed = TRUE;
}
else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`'))
{
BigBuffer[ptr] = '"'; ptr ++;
i += 2;
changed = TRUE;
}
else if (!inVerbatim && ch == '`') // Change ` to '
{
BigBuffer[ptr] = 39; ptr ++;
i += 1;
changed = TRUE;
}
else
{
BigBuffer[ptr] = ch;
i ++;
ptr ++;
}
}
BigBuffer[ptr] = 0;
if (changed)
{
delete chunk->value;
chunk->value = copystring(BigBuffer);
}
}
/*
* Scan through all chunks starting from the given one,
* calling ProcessText2HTML to convert Latex-isms to RTF-isms.
* This should be called after Tex2Any has parsed the file,
* and before TraverseDocument is called.
*
*/
void Text2HTML(TexChunk *chunk)
{
switch (chunk->type)
{
case CHUNK_TYPE_MACRO:
{
TexMacroDef *def = NULL;
wxNode *node = MacroDefs.Find(chunk->name);
if (node)
{
def = (TexMacroDef *)node->Data();
if (def->ignore)
return;
}
if (def && strcmp(def->name, "verbatim") == 0)
inVerbatim = TRUE;
node = chunk->children.First();
while (node)
{
TexChunk *child_chunk = (TexChunk *)node->Data();
Text2HTML(child_chunk);
node = node->Next();
}
if (def && strcmp(def->name, "verbatim") == 0)
inVerbatim = FALSE;
break;
}
case CHUNK_TYPE_ARG:
{
wxNode *node = chunk->children.First();
while (node)
{
TexChunk *child_chunk = (TexChunk *)node->Data();
Text2HTML(child_chunk);
node = node->Next();
}
break;
}
case CHUNK_TYPE_STRING:
{
if (chunk->value)
ProcessText2HTML(chunk);
break;
}
}
}
// Called on start/end of macro examination
void HTMLOnMacro(char *name, int no_args, Bool start)
{
if (strcmp(name, "chapter") == 0 || strcmp(name, "chapter*") == 0 || strcmp(name, "myheading") == 0)
{
if (start)
{
if (CurrentLabel)
{
delete[] CurrentLabel;
CurrentLabel = NULL;
}
ReopenFile(&Chapters, &ChaptersName);
SetCurrentOutput(NULL);
startedSections = TRUE;
}
else
{
char *topicName = FindTopicName(GetNextChunk());
AddTexRef(topicName, ChaptersName, "chapter");
SetCurrentOutput(Chapters);
TexOutput("<title>");
TraverseChildrenFromChunk(currentSection);
TexOutput("</title>\n");
SetCurrentOutputs(Contents, Chapters);
fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">\n", ChaptersName, topicName);
fprintf(Chapters, "<A NAME=\"%s\">\n<H2>", topicName);
TraverseChildrenFromChunk(currentSection);
fprintf(Contents, "\n</A>\n");
fprintf(Chapters, "</H2>\n</A>\n");
SetCurrentOutput(Chapters);
}
}
else if (strcmp(name, "section") == 0 || strcmp(name, "section*") == 0 ||
strcmp(name, "gloss") == 0 || strcmp(name, "problem") == 0)
{
if (start)
{
if (CurrentLabel)
{
delete[] CurrentLabel;
CurrentLabel = NULL;
}
ReopenFile(&Sections, &SectionsName);
SetCurrentOutput(NULL);
startedSections = TRUE;
}
else
{
char *topicName = FindTopicName(GetNextChunk());
AddTexRef(topicName, SectionsName, "section");
SetCurrentOutput(Sections);
TexOutput("<title>");
TraverseChildrenFromChunk(currentSection);
TexOutput("</title>\n");
FILE *jumpFrom = ((DocumentStyle == LATEX_ARTICLE) ? Contents : Chapters);
SetCurrentOutputs(jumpFrom, Sections);
if (DocumentStyle == LATEX_ARTICLE)
fprintf(jumpFrom, "\n<LI><A HREF=\"%s#%s\">\n", SectionsName, topicName);
else
fprintf(jumpFrom, "\n<A HREF=\"%s#%s\">\n<B>", SectionsName, topicName);
fprintf(Sections, "<A NAME=\"%s\">\n<H2>", topicName);
TraverseChildrenFromChunk(currentSection);
if (DocumentStyle == LATEX_ARTICLE)
fprintf(jumpFrom, "\n</A>\n");
else
fprintf(jumpFrom, "</B>\n</A><P>\n");
fprintf(Sections, "</H2>\n</A>\n");
SetCurrentOutput(Sections);
}
}
else if (strcmp(name, "references") == 0)
{
char *jumpToName;
FILE *jumpTo;
if (DocumentStyle == LATEX_ARTICLE)
{
jumpToName = SectionsName;
jumpTo = Sections;
}
else
{
jumpToName = ChaptersName;
jumpTo = Chapters;
}
if (start)
{
if (CurrentLabel)
{
delete[] CurrentLabel;
CurrentLabel = NULL;
}
ReopenFile(&jumpTo, &jumpToName);
startedSections = TRUE;
SetCurrentOutput(jumpTo);
TexOutput("<title>References</title>\n");
char *topicName = "references";
SetCurrentOutputs(Contents, jumpTo);
fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">\n", jumpToName, topicName);
fprintf(jumpTo, "<A NAME=\"%s\">\n<H2>", topicName);
TexOutput("References");
fprintf(Contents, "\n</A>\n");
fprintf(jumpTo, "</H2>\n</A>\n");
SetCurrentOutput(jumpTo);
TexOutput("<DL>\n");
}
}
else if (strcmp(name, "subsection") == 0 || strcmp(name, "subsection*") == 0 ||
strcmp(name, "membersection") == 0 || strcmp(name, "functionsection") == 0)
{
if (start)
{
if (CurrentLabel)
{
delete[] CurrentLabel;
CurrentLabel = NULL;
}
ReopenFile(&Subsections, &SubsectionsName);
SetCurrentOutput(NULL);
startedSections = TRUE;
}
else
{
char *topicName = FindTopicName(GetNextChunk());
AddTexRef(topicName, SubsectionsName, "subsection");
SetCurrentOutput(Subsections);
TexOutput("<title>");
TraverseChildrenFromChunk(currentSection);
TexOutput("</title>\n");
SetCurrentOutputs(Sections, Subsections);
fprintf(Sections, "\n<A HREF=\"%s#%s\">\n<B>", SubsectionsName, topicName);
fprintf(Subsections, "<A NAME=\"%s\">\n<H2>", topicName);
TraverseChildrenFromChunk(currentSection);
fprintf(Sections, "</B>\n</A><P>\n");
fprintf(Subsections, "</H2>\n</A>\n");
SetCurrentOutput(Subsections);
}
}
else if (strcmp(name, "subsubsection") == 0)
{
if (start)
{
if (CurrentLabel)
{
delete[] CurrentLabel;
CurrentLabel = NULL;
}
ReopenFile(&Subsubsections, &SubsubsectionsName);
SetCurrentOutput(NULL);
startedSections = TRUE;
}
else
{
char *topicName = FindTopicName(GetNextChunk());
AddTexRef(topicName, SubsubsectionsName, "subsubsection");
SetCurrentOutput(Subsubsections);
TexOutput("<title>");
TraverseChildrenFromChunk(currentSection);
TexOutput("</title>\n");
SetCurrentOutputs(Subsections, Subsubsections);
fprintf(Subsections, "\n<A HREF=\"%s#%s\">\n<B>", SubsubsectionsName, topicName);
fprintf(Subsubsections, "<A NAME=\"%s\">\n<H3>", topicName);
TraverseChildrenFromChunk(currentSection);
fprintf(Subsections, "</B>\n</A><P>\n");
fprintf(Subsubsections, "</H3>\n</A>\n");
SetCurrentOutput(Subsubsections);
}
}
else if ((strcmp(name, "func") == 0) || (strcmp(name, "pfunc") == 0))
{
SetCurrentOutput(Subsections);
if (start)
{
}
else
{
}
}
else if (strcmp(name, "clipsfunc") == 0)
{
SetCurrentOutput(Subsections);
if (start)
{
}
else
{
}
}
else if (strcmp(name, "member") == 0)
{
SetCurrentOutput(Subsections);
if (start)
{
}
else
{
}
}
else if ((strcmp(name, "void") == 0) && start)
TexOutput("<B>void</B>");
else if ((strcmp(name, "hardy") == 0) && start)
TexOutput("HARDY");
else if ((strcmp(name, "wxclips") == 0) && start)
TexOutput("wxCLIPS");
else if ((strcmp(name, "&") == 0) && start)
TexOutput("&");
else if ((strcmp(name, "\\") == 0) && start)
TexOutput("\n");
else if ((strcmp(name, "rtfsp") == 0) && start) // Explicit space, RTF only
{}
else if ((strcmp(name, "itemize") == 0) ||
(strcmp(name, "enumerate") == 0) ||
(strcmp(name, "description") == 0))
{
if (start)
{
indentLevel ++;
int listType;
if (strcmp(name, "enumerate") == 0)
listType = LATEX_ENUMERATE;
else if (strcmp(name, "itemize") == 0)
listType = LATEX_ITEMIZE;
else
listType = LATEX_DESCRIPTION;
itemizeStack.Insert(new ItemizeStruc(listType));
switch (listType)
{
case LATEX_ITEMIZE:
TexOutput("<UL>\n");
break;
case LATEX_ENUMERATE:
TexOutput("<OL>\n");
break;
case LATEX_DESCRIPTION:
TexOutput("<DL>\n");
break;
}
}
else
{
indentLevel --;
if (itemizeStack.First())
{
ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
switch (struc->listType)
{
case LATEX_ITEMIZE:
TexOutput("</UL>\n");
break;
case LATEX_ENUMERATE:
TexOutput("</OL>\n");
break;
case LATEX_DESCRIPTION:
TexOutput("</DL>\n");
break;
}
delete struc;
delete itemizeStack.First();
}
}
}
else if (strcmp(name, "par") == 0)
{
if (start)
TexOutput("<P>\n");
}
else if (strcmp(name, "verbatim") == 0)
{
if (start)
{
char buf[100];
sprintf(buf, "<PRE>\n");
TexOutput(buf);
}
else TexOutput("</PRE>\n");
}
else if (strcmp(name, "centerline") == 0 || strcmp(name, "center") == 0)
{
/*
if (start)
{
TexOutput("{\\qc ");
}
else TexOutput("}\\par\\pard\n");
*/
}
else if (strcmp(name, "flushleft") == 0)
{
/*
if (start)
{
TexOutput("{\\ql ");
}
else TexOutput("}\\par\\pard\n");
*/
}
else if (strcmp(name, "flushright") == 0)
{
/*
if (start)
{
TexOutput("{\\qr ");
}
else TexOutput("}\\par\\pard\n");
*/
}
else if (strcmp(name, "small") == 0)
{
/*
if (start)
{
TexOutput("{\\fs16\n");
}
else TexOutput("}\n");
*/
}
else if (strcmp(name, "tiny") == 0)
{
/*
if (start)
{
TexOutput("{\\fs12\n");
}
else TexOutput("}\n");
*/
}
else if (strcmp(name, "normalsize") == 0)
{
/*
if (start)
{
TexOutput("{\\fs20\n");
}
else TexOutput("}\n");
*/
}
else if (strcmp(name, "large") == 0)
{
/*
if (start)
{
TexOutput("{\\fs24\n");
}
else TexOutput("}\n");
*/
}
else if (strcmp(name, "LARGE") == 0)
{
if (start)
{
TexOutput("<H1>");
}
else TexOutput("</H1>");
}
else if (strcmp(name, "Large") == 0)
{
if (start)
{
TexOutput("<H1>");
}
else TexOutput("</H1>");
}
else if (strcmp(name, "bf") == 0)
{
if (start)
{
TexOutput("<B>");
}
else TexOutput("</B>");
}
else if (strcmp(name, "it") == 0)
{
if (start)
{
TexOutput("<I>");
}
else TexOutput("</I>");
}
else if (strcmp(name, "tt") == 0)
{
if (start)
{
TexOutput("<TT>");
}
else TexOutput("</TT>");
}
else if (strcmp(name, "sc") == 0)
{
}
else if (strcmp(name, "item") == 0)
{
if (start)
{
wxNode *node = itemizeStack.First();
if (node)
{
ItemizeStruc *struc = (ItemizeStruc *)node->Data();
struc->currentItem += 1;
// if (struc->currentItem > 1)
// TexOutput("<P>\n");
if (struc->listType == LATEX_DESCRIPTION)
{
if (descriptionItemArg)
{
TexOutput("<DT>");
TraverseChildrenFromChunk(descriptionItemArg);
TexOutput("\n");
descriptionItemArg = NULL;
}
TexOutput("<DD>");
}
else
TexOutput("<LI>");
}
}
}
else if (strcmp(name, "maketitle") == 0)
{
if (start && DocumentTitle && DocumentAuthor)
{
TexOutput("<H1>");
TraverseChildrenFromChunk(DocumentTitle);
TexOutput("</H1><P>\n\n");
TexOutput("<H3>");
TraverseChildrenFromChunk(DocumentAuthor);
TexOutput("</H3><P>\n\n");
if (DocumentDate)
{
TexOutput("<H3>");
TraverseChildrenFromChunk(DocumentDate);
TexOutput("</H3><P>\n\n");
}
}
}
else if (strcmp(name, "helpref") == 0 || strcmp(name, "helprefn") == 0)
{
if (start)
{
helpRefFilename = NULL;
helpRefText = NULL;
}
}
else if (strcmp(name, "bibliography") == 0)
{
if (start)
{
DefaultOnMacro(name, no_args, start);
}
else
{
DefaultOnMacro(name, no_args, start);
TexOutput("</DL>\n");
}
}
else if (strcmp(name, "hrule") == 0)
{
if (start)
{
TexOutput("<P>------------------------------------------------------------------<P>\n");
}
}
else if (strcmp(name, "tableofcontents") == 0)
{
if (start)
{
FILE *fd = fopen(ContentsName, "r");
if (fd)
{
char ch = getc(fd);
while (ch != EOF)
{
putc(ch, Titlepage);
ch = getc(fd);
}
fclose(fd);
}
else
{
TexOutput("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n");
OnInform("Run Tex2RTF again to include contents page.");
}
}
}
else DefaultOnMacro(name, no_args, start);
}
// Called on start/end of argument examination
Bool HTMLOnArgument(char *macro_name, int arg_no, Bool start)
{
if ((strcmp(macro_name, "chapter") == 0) ||
(strcmp(macro_name, "chapter*") == 0) ||
(strcmp(macro_name, "myheading") == 0) ||
(strcmp(macro_name, "section") == 0) ||
(strcmp(macro_name, "section*") == 0) ||
(strcmp(macro_name, "subsection") == 0) ||
(strcmp(macro_name, "subsection*") == 0) ||
(strcmp(macro_name, "subsubsection") == 0) ||
(strcmp(macro_name, "subsubsection*") == 0) ||
(strcmp(macro_name, "gloss") == 0) ||
(strcmp(macro_name, "membersection") == 0) ||
(strcmp(macro_name, "functionsection") == 0))
{
if (!start && (arg_no == 1))
currentSection = GetArgChunk();
}
else if (strcmp(macro_name, "func") == 0)
{
if (start && (arg_no == 1))
TexOutput("<B>");
if (!start && (arg_no == 1))
TexOutput("</B> ");
if (start && (arg_no == 2))
{
if (!suppressNameDecoration) TexOutput("<B>");
currentMember = GetArgChunk();
}
if (!start && (arg_no == 2))
{
if (!suppressNameDecoration) TexOutput("</B>");
}
if (start && (arg_no == 3))
TexOutput("(");
if (!start && (arg_no == 3))
TexOutput(")");
}
else if (strcmp(macro_name, "clipsfunc") == 0)
{
if (start && (arg_no == 1))
TexOutput("<B>");
if (!start && (arg_no == 1))
TexOutput("</B> ");
if (start && (arg_no == 2))
{
if (!suppressNameDecoration) TexOutput("( ");
currentMember = GetArgChunk();
}
if (!start && (arg_no == 2))
{
}
if (!start && (arg_no == 3))
TexOutput(")");
}
else if (strcmp(macro_name, "pfunc") == 0)
{
if (!start && (arg_no == 1))
TexOutput(" ");
if (start && (arg_no == 2))
TexOutput("(*");
if (!start && (arg_no == 2))
TexOutput(")");
if (start && (arg_no == 2))
currentMember = GetArgChunk();
if (start && (arg_no == 3))
TexOutput("(");
if (!start && (arg_no == 3))
TexOutput(")");
}
else if (strcmp(macro_name, "param") == 0)
{
if (start && (arg_no == 1))
TexOutput("<B>");
if (!start && (arg_no == 1))
TexOutput("</B>");
if (start && (arg_no == 2))
{
TexOutput("<I>");
}
if (!start && (arg_no == 2))
{
TexOutput("</I>");
}
}
else if (strcmp(macro_name, "cparam") == 0)
{
if (start && (arg_no == 1))
TexOutput("<B>");
if (!start && (arg_no == 1))
TexOutput("</B> "); // This is the difference from param - one space!
if (start && (arg_no == 2))
{
TexOutput("<I>");
}
if (!start && (arg_no == 2))
{
TexOutput("</I>");
}
}
else if (strcmp(macro_name, "member") == 0)
{
if (!start && (arg_no == 1))
TexOutput(" ");
if (start && (arg_no == 2))
currentMember = GetArgChunk();
}
else if (strcmp(macro_name, "helpref") == 0 || strcmp(macro_name, "helprefn") == 0)
{
if (IsArgOptional())
{
if (start)
helpRefFilename = GetArgChunk();
return FALSE;
}
else if ((GetNoArgs() - arg_no) == 1)
{
if (start)
helpRefText = GetArgChunk();
return FALSE;
}
else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
{
if (start)
{
char *refName = GetArgData();
char *refFilename = NULL;
if (refName)
{
wxNode *node = TexReferences.Find(refName);
if (node)
{
TexRef *texRef = (TexRef *)node->Data();
if (texRef->refFile && strcmp(texRef->refFile, "??") != 0)
refFilename = texRef->refFile;
TexOutput("<A HREF=\"");
// If a filename is supplied, use it, otherwise try to
// use the filename associated with the reference (from this document).
if (helpRefFilename)
{
TraverseChildrenFromChunk(helpRefFilename);
TexOutput("#");
}
else if (refFilename)
{
TexOutput(refFilename);
TexOutput("#");
}
TexOutput(refName);
TexOutput("\">");
if (helpRefText)
TraverseChildrenFromChunk(helpRefText);
TexOutput("</A>");
}
}
else TexOutput("??");
}
return FALSE;
}
}
else if (strcmp(macro_name, "psboxto") == 0 || strcmp(macro_name, "image") == 0)
{
if (arg_no == 2)
{
if (start)
TexOutput("<A HREF=\"");
else
TexOutput("\">Picture<P>\n");
}
else return FALSE;
}
else if (strcmp(macro_name, "item") == 0)
{
if (start && IsArgOptional())
{
descriptionItemArg = GetArgChunk();
return FALSE;
}
}
else if (strcmp(macro_name, "bibitem") == 0)
{
if (arg_no == 1 && start)
TexOutput("\n<DT>");
if (arg_no == 2 && start)
TexOutput("\n<DD>");
if (arg_no == 2 && !start)
TexOutput("<P>\n");
}
else return DefaultOnArgument(macro_name, arg_no, start);
return TRUE;
}
Bool HTMLGo(void)
{
fileId = 0;
inVerbatim = FALSE;
indentLevel = 0;
if (InputFile && OutputFile)
{
// Do some HTML-specific transformations on all the strings,
// recursively
Text2HTML(GetTopLevelChunk());
char buf[300];
sprintf(buf, "%s_contents.html", FileRoot);
Titlepage = fopen(buf, "w");
Contents = fopen(TmpContentsName, "w");
if (!Titlepage || !Contents)
{
OnError("Cannot open output file!");
return FALSE;
}
fprintf(Contents, "<P><P><H1>Contents</H1><P><P>\n");
fprintf(Contents, "<UL>\n");
SetCurrentOutput(Titlepage);
OnInform("Converting...");
TraverseDocument();
if (DocumentTitle)
{
SetCurrentOutput(Titlepage);
TexOutput("\n<TITLE>");
TraverseChildrenFromChunk(DocumentTitle);
TexOutput("</TITLE>\n");
}
else
{
if (contentsString)
fprintf(Titlepage, "<TITLE>%s</TITLE>\n\n", contentsString);
else
fprintf(Titlepage, "<TITLE>%s</TITLE>\n\n", FileNameFromPath(FileRoot));
}
fprintf(Contents, "</UL>\n\n");
if (Titlepage)
fclose(Titlepage);
if (Contents)
fclose(Contents);
if (Chapters)
fclose(Chapters);
if (Sections)
fclose(Sections);
if (Subsections)
fclose(Subsections);
if (Subsubsections)
fclose(Subsubsections);
if (FileExists(ContentsName)) wxRemoveFile(ContentsName);
wxRenameFile(TmpContentsName, ContentsName);
return TRUE;
}
return FALSE;
}